package mspbots.data.tl.prod.quickbooks.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.log4j.Log4j2;
import mspbots.data.tl.base.AbstractBaseServiceImpl;
import mspbots.data.tl.entity.ResultEntity;
import mspbots.data.tl.prod.quickbooks.mapper.OnlineAccountMapper;
import mspbots.data.tl.prod.quickbooks.model.OnlineAccount;
import mspbots.data.tl.prod.quickbooks.service.OnlineAccountService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author Jay.Yang
 */

@Service
@Log4j2
@DS("master")
public class OnlineAccountServiceImpl extends AbstractBaseServiceImpl<OnlineAccountMapper, OnlineAccount>
        implements OnlineAccountService {

    @Override
    public void sync(ResultEntity resultEntity) {
        JsonNode entity = resultEntity.getEntity();
        OnlineAccount data = OnlineAccount.builder()
                .accountId(ObjectUtils.isEmpty(entity.get("Id")) ? null : entity.get("Id").asInt())
                .active(ObjectUtils.isEmpty(entity.get("Active")) ? null : entity.get("Active").asBoolean())
                .name(ObjectUtils.isEmpty(entity.get("Name")) ? null : entity.get("Name").asText())
                .acctNum(ObjectUtils.isEmpty(entity.get("AcctNum")) ? null : entity.get("AcctNum").asText())
                .domain(ObjectUtils.isEmpty(entity.get("domain")) ? null : entity.get("domain").asText())
                .sparse(ObjectUtils.isEmpty(entity.get("sparse")) ? null : entity.get("sparse").asBoolean())
                .syncToken(ObjectUtils.isEmpty(entity.get("SyncToken")) ? null : entity.get("SyncToken").asText())
                .subAccount(ObjectUtils.isEmpty(entity.get("SubAccount")) ? null : entity.get("SubAccount").asBoolean())
                .accountType(ObjectUtils.isEmpty(entity.get("AccountType")) ? null : entity.get("AccountType").asText())
                .currencyRefName(ObjectUtils.isEmpty(entity.get("CurrencyRef")) ? null :
                        ObjectUtils.isEmpty(entity.get("CurrencyRef").get("name")) ? null : entity.get("CurrencyRef").get("name").asText())
                .currencyRefValue(ObjectUtils.isEmpty(entity.get("CurrencyRef")) ? null :
                        ObjectUtils.isEmpty(entity.get("CurrencyRef").get("name")) ? null : entity.get("CurrencyRef").get("value").asText())
                .accountSubType(ObjectUtils.isEmpty(entity.get("AccountSubType")) ? null : entity.get("AccountSubType").asText())
                .classification(ObjectUtils.isEmpty(entity.get("Classification")) ? null : entity.get("Classification").asText())
                .currentBalance(ObjectUtils.isEmpty(entity.get("CurrentBalance")) ? null : entity.get("CurrentBalance").asDouble())
                .fullyQualifiedName(ObjectUtils.isEmpty(entity.get("FullyQualifiedName")) ? null : entity.get("FullyQualifiedName").asText())
                .currentBalanceWithSubAccounts(ObjectUtils.isEmpty(entity.get("CurrentBalanceWithSubAccounts")) ? null : entity.get("CurrentBalanceWithSubAccounts").asDouble())
                .syncTime(resultEntity.getSyncDate())
                .build();

        if (!ObjectUtils.isEmpty(entity.get("MetaData"))){
            ZonedDateTime createTime = ZonedDateTime.parse(entity.get("MetaData").get("CreateTime").asText(),
                    DateTimeFormatter.ISO_OFFSET_DATE_TIME).withZoneSameInstant(ZoneOffset.UTC);
            ZonedDateTime LastUpdatedTime = ZonedDateTime.parse(entity.get("MetaData").get("LastUpdatedTime").asText(),
                    DateTimeFormatter.ISO_OFFSET_DATE_TIME).withZoneSameInstant(ZoneOffset.UTC);
            data.setCreateTime(createTime.toLocalDateTime());
            data.setLastUpdatedTime(LastUpdatedTime.toLocalDateTime());
        }
        data.setTenantCode(resultEntity.getTenantId());

        OnlineAccount dbData = super.baseMapper.selectOne(Wrappers.<OnlineAccount>lambdaQuery()
                .eq(OnlineAccount::getTenantCode, data.getTenantCode())
                .eq(OnlineAccount::getAccountId, data.getAccountId())
                .last("limit 1"));

        if (ObjectUtils.isEmpty(dbData)){
            super.baseMapper.insert(data);
        }else{
            data.setId(dbData.getId());
            super.baseMapper.updateById(data);
        }

    }
}
